package base

import (
	"log"
	"net"
	"strings"
)

type User struct {
	Name   string
	Addr   string
	C      chan string
	conn   net.Conn
	server *Server
}

// NewUser 创建一个用户
func NewUser(name string, conn net.Conn, s *Server) *User {
	addr := conn.RemoteAddr().String()
	user := &User{
		Name:   name,
		Addr:   addr,
		C:      make(chan string, 100),
		conn:   conn,
		server: s,
	}

	// 启动监听用户消息的协程 非main函数返回时，它并不会直接导致整个程序退出，包括其启动的子协程
	go user.ListenMsg()

	return user
}

// Online 用户上线
func (u *User) Online() {
	// 将用户添加到在线列表
	u.server.mapLock.Lock()
	u.server.OnlineMap[u.Name] = u
	u.server.mapLock.Unlock()

	// 广播
	u.server.BroadCast(u, "已上线")
}

// Offline 用户下线
func (u *User) Offline() {
	// 将用户从在线列表中删除
	u.server.mapLock.Lock()
	delete(u.server.OnlineMap, u.Name)
	u.server.mapLock.Unlock()

	// 广播
	u.server.BroadCast(u, "已下线")
}

// SendMsg 发送消息
func (u *User) SendMsg(msg string) {
	u.conn.Write([]byte(msg))
}

func (u *User) DoMessage(msg string) {
	log.Println("接收到的消息：", msg)
	if msg == "who" {
		// 查询当前在线用户列表
		u.server.mapLock.Lock()
		for _, user := range u.server.OnlineMap {
			onlineMsg := "[" + user.Addr + "]" + user.Name + ":" + "在线...\n"
			u.SendMsg(onlineMsg)
		}
		u.server.mapLock.Unlock()
	} else if strings.HasPrefix(msg, "rename|") {		
		// 获取新的用户名
		newName := strings.Split(msg, "|")[1]
		// 判断用户名是否可用
		_, ok := u.server.OnlineMap[newName]
		if ok {
			u.SendMsg("用户名已存在")
		} else {
			// 将用户名修改
			u.server.mapLock.Lock()
			// 删除旧用户名
			delete(u.server.OnlineMap, u.Name)
			// 添加新用户名
			u.Name = newName
			u.server.OnlineMap[u.Name] = u
			u.server.mapLock.Unlock()
			u.SendMsg("用户名修改成功")
			//u.server.BroadCast(u, "已修改用户名")
			return
		}
	} else if strings.HasPrefix(msg, "to|") {
		// 发送消息
		msgArr := strings.Split(msg, "|")
		toUserName := msgArr[1]
		toUser, ok := u.server.OnlineMap[toUserName]
		if !ok {
			u.SendMsg("用户不存在")
			return
		}
		toUser.SendMsg(u.Name + "对你说：" + msgArr[2])
		return
	} else{
		u.server.BroadCast(u, msg)
	}
}

// ListenMsg 监听用户消息
func (u *User) ListenMsg() {
	for {
		msg := <-u.C
		u.conn.Write([]byte(msg + "\n"))
	}
}